package ar.uade.distribuidas.tpo.dba.dominio;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.joda.time.DateTime;

import com.google.common.collect.Maps;

@Entity
@Table(name = "remitos")
public class Remito {
	@Id
	private int numero;
	@OneToOne
	private Cliente cliente;
	@OneToMany(cascade = CascadeType.ALL)
	@JoinTable(name = "remitos_items", joinColumns = @JoinColumn(name = "remito_id"), inverseJoinColumns = @JoinColumn(name = "item_id"))
	private List<ItemRemito> itemsRemito;
	private EstadoRemito estado;
	private DateTime fecha;

	public Remito(int numero, Cliente cliente, EstadoRemito estado, DateTime fecha) {
		super();
		this.numero = numero;
		this.cliente = cliente;
		this.itemsRemito = new ArrayList<ItemRemito>();
		this.estado = estado;
		this.fecha = fecha;
	}
	
	public Map<OrdenDePedido, List<ItemRemito>> getItemsPorOrdenDePedido() {
		Map<OrdenDePedido, List<ItemRemito>> itemsPorOP = Maps.newHashMap();
		
		for (ItemRemito item : itemsRemito) {
			OrdenDePedido o = item.getOp();
			
			if (!itemsPorOP.containsKey(o)) {
				itemsPorOP.put(o, new LinkedList<ItemRemito>());
			}
			
			itemsPorOP.get(o).add(item);
		}
		
		return itemsPorOP;
	}

	public DateTime getFecha() {
		return fecha;
	}

	public void setFecha(DateTime fecha) {
		this.fecha = fecha;
	}

	public int getNumero() {
		return numero;
	}

	public void setNumero(int numero) {
		this.numero = numero;
	}

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

	public List<ItemRemito> getItemsRemito() {
		return itemsRemito;
	}

	public void setItemsRemito(List<ItemRemito> itemsRemito) {
		this.itemsRemito = itemsRemito;
	}

	public EstadoRemito getEstado() {
		return estado;
	}

	public void setEstado(EstadoRemito estado) {
		this.estado = estado;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cliente == null) ? 0 : cliente.hashCode());
		result = prime * result + ((estado == null) ? 0 : estado.hashCode());
		result = prime * result + ((fecha == null) ? 0 : fecha.hashCode());
		result = prime * result + ((itemsRemito == null) ? 0 : itemsRemito.hashCode());
		result = prime * result + numero;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Remito other = (Remito) obj;
		if (cliente == null) {
			if (other.cliente != null)
				return false;
		} else if (!cliente.equals(other.cliente))
			return false;
		if (estado != other.estado)
			return false;
		if (fecha == null) {
			if (other.fecha != null)
				return false;
		} else if (!fecha.equals(other.fecha))
			return false;
		if (itemsRemito == null) {
			if (other.itemsRemito != null)
				return false;
		} else if (!itemsRemito.equals(other.itemsRemito))
			return false;
		if (numero != other.numero)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Remito [numero=" + numero + ", cliente=" + cliente + ", itemsRemito=" + itemsRemito + ", estado=" + estado
				+ ", fecha=" + fecha + "]";
	}

}
